package com.n5x.service.impl;

import com.n5x.mapper.user.UserAccountMapper;
import com.n5x.mapper.user.UserDisCountMapper;
import com.n5x.mapper.user.UserInfoMapper;
import com.n5x.mapper.user.UserTransactionRecordMapper;
import com.n5x.model.AbstractModel;
import com.n5x.model.user.*;
import com.n5x.service.IUserService;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/9/22.
 */
@Service
@Transactional
public class IUserServiceImpl implements IUserService {

    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    UserAccountMapper userAccountMapper;

    @Autowired
    UserTransactionRecordMapper userTransactionRecordMapper;

    @Autowired
    UserDisCountMapper userDisCountMapper;

    // UserInfo

    /**
     * 保存或更新用户信息，并保存用户绑定账号信息
     *
     * @param userInfo    用户
     * @param userAccount 账号
     * @return 用户ID
     */
    public UserInfo saveUserInfoAndAccount(UserInfo userInfo, UserAccount userAccount) {
        userInfo.setLastUpdateTime(new Date());
        if (StringUtils.isBlank(userInfo.getFkLevel())) {
            userInfo.setFkLevel("0");
        }
        if (StringUtils.isBlank(userInfo.getId())) {
            userInfo.init();
            //注册优惠
            userInfo.setBalance(userInfo.getBalance().add(new BigDecimal(5)));
            userInfo.setFkLevel("1");
            userInfoMapper.insert(userInfo);
            //注册赠送"
//            UserTransactionRecord userTransactionRecord = new UserTransactionRecord(userInfo.getId(),userAccount.getLoginName(), UserTransactionRecord.Method.余额,UserTransactionRecord.TransactionType.赠送,new BigDecimal()).setNote("注册赠送");
//            userTransactionRecord.setDisable(Boolean.FALSE);
//            userTransactionRecordMapper.insert(userTransactionRecord);
        } else {
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
        }
        userAccount.setFkUserId(userInfo.getId());
        if (StringUtils.isBlank(userAccount.getId())) {
            userAccount.init();
            userAccountMapper.insert(userAccount);
        } else {
            userAccountMapper.updateByPrimaryKeySelective(userAccount);
        }
        return userInfo;
    }

    /**
     * 保存或更新用户信息
     *
     * @param userInfo
     * @return
     */
    public String saveUserInfo(UserInfo userInfo) {
        userInfo.setLastUpdateTime(new Date());
        if (StringUtils.isBlank(userInfo.getId())) {
            userInfo.init();
            userInfoMapper.insert(userInfo);
        } else {
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
        }
        return userInfo.getId();
    }

    public String saveUserAccount(UserAccount userAccount) {
        userAccount.setLastUpdateTime(new Date());
        if (StringUtils.isBlank(userAccount.getId())) {
            userAccount.init();
            userAccountMapper.insert(userAccount);
        } else {
            userAccountMapper.updateByPrimaryKeySelective(userAccount);
        }
        return userAccount.getId();
    }

    /**
     * 查找用户信息
     *
     * @param criteria 查询条件[可选]
     * @return 用户列表
     */
    public List<UserInfo> findUserInfoAll(UserInfoExample.Criteria criteria) {
        UserInfoExample userInfoExample = new UserInfoExample();
        if (criteria == null) {
            criteria = userInfoExample.or();
        } else {
            userInfoExample.or(criteria);
        }
        userInfoExample.setOrderByClause(AbstractModel.ORDER);
        return userInfoMapper.selectByExample(userInfoExample);
    }

    /**
     * 查找用户信息
     *
     * @param criteria 查询条件[可选]
     * @return 用户列表
     */
    public int countUserInfoAll(UserInfoExample.Criteria criteria) {
        UserInfoExample userInfoExample = new UserInfoExample();
        if (criteria == null) {
            criteria = userInfoExample.or();
        } else {
            userInfoExample.or(criteria);
        }
        userInfoExample.setOrderByClause(AbstractModel.ORDER);
        return userInfoMapper.countByExample(userInfoExample);
    }

    /**
     * 按账号类型、登陆名称、密码查找用户信息
     *
     * @param type
     * @param login 登陆名称
     * @param pwd   密码
     * @return 用户对象，没有为null
     * @see UserAccount.AccountType
     */
    public UserInfo findUserByAccount(Enum<UserAccount.AccountType> type, String login, String pwd) {
        Assert.notNull(login, "登陆名称不能为空");
        Assert.notNull(type, "登陆类型不能为空");
        UserAccountExample userAccountExample = new UserAccountExample();
        UserAccountExample.Criteria criteria = userAccountExample.or();
        criteria.andTypeEqualTo(type.name()).andLoginNameEqualTo(login).andDisableEqualTo(Boolean.FALSE).andFkUserIdIsNotNull();
        if (StringUtils.isNotBlank(pwd)) {
            pwd = UserAccount.encodePassword(pwd);
            criteria.andPasswordEqualTo(pwd);
        }
        List<UserAccount> userAccountList = userAccountMapper.selectByExample(userAccountExample);
        if (CollectionUtils.isNotEmpty(userAccountList)) {
            String userId = userAccountList.iterator().next().getFkUserId();
            if (StringUtils.isNotBlank(userId)) return userInfoMapper.selectByPrimaryKey(userId);
        }
        return null;
    }

    /**
     * 查找用户信息
     *
     * @param id
     * @return 用户信息
     */
    public UserInfo findUserInfo(String id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }

    public List<UserInfo> findUserInfoByPhone(String phone) {
        UserInfoExample userInfoExample = new UserInfoExample();
        userInfoExample.or().andPhoneEqualTo(phone).andDisableEqualTo(Boolean.FALSE);
        List<UserInfo> userInfoList = userInfoMapper.selectByExample(userInfoExample);
        return userInfoList;
    }

    // UserAccount

    /**
     * 检查账号登陆名是否存在
     *
     * @param type  账号类型
     * @param login 登陆名
     * @return 是否存在
     */
    public boolean cheackUserByAccount(Enum<UserAccount.AccountType> type, String login) {
        Assert.notNull(type, "登陆类型不能为空");
        Assert.notNull(login, "登陆名称不能为空");
        UserAccountExample userAccountExample = new UserAccountExample();
        userAccountExample.or().andTypeEqualTo(type.name()).andLoginNameEqualTo(login).andDisableEqualTo(Boolean.FALSE).andFkUserIdIsNotNull();
        return userAccountMapper.countByExample(userAccountExample) > 0;
    }

    public UserAccount findAccountByName(Enum<UserAccount.AccountType> type, String login) {
        Assert.notNull(type, "登陆类型不能为空");
        Assert.notNull(login, "登陆名称不能为空");
        UserAccountExample userAccountExample = new UserAccountExample();
        userAccountExample.or().andTypeEqualTo(type.name()).andLoginNameEqualTo(login).andDisableEqualTo(Boolean.FALSE).andFkUserIdIsNotNull();
        List<UserAccount> userAccounts = userAccountMapper.selectByExample(userAccountExample);

        return userAccounts.size() > 0 ? userAccounts.get(0) : null;
    }

    public UserInfo findUserInfoByLogin(String login) {
        UserAccountExample userAccountExample = new UserAccountExample();
        UserAccountExample.Criteria criteria = userAccountExample.or();
        criteria.andLoginNameEqualTo(login).andDisableEqualTo(Boolean.FALSE).andFkUserIdIsNotNull();

        List<UserAccount> userAccountList = userAccountMapper.selectByExample(userAccountExample);
        if (CollectionUtils.isNotEmpty(userAccountList)) {
            String userId = userAccountList.iterator().next().getFkUserId();
            if (StringUtils.isNotBlank(userId)) return userInfoMapper.selectByPrimaryKey(userId);
        }
        return null;
    }

    //******************************************** UserTransactionRecord  ****************************************************
    public List<UserTransactionRecord> findUserTransactionRecordAll(UserTransactionRecordExample.Criteria criteria) {
        UserTransactionRecordExample userTransactionRecordExample = new UserTransactionRecordExample();
        if (criteria == null) {
            criteria = userTransactionRecordExample.createCriteria();
        } else {
            userTransactionRecordExample.or(criteria);
        }
        userTransactionRecordExample.setOrderByClause(AbstractModel.ORDER);
        return userTransactionRecordMapper.selectByExampleWithBLOBs(userTransactionRecordExample);
    }

    public UserTransactionRecord findUserTransactionRecord(String id) {
        return userTransactionRecordMapper.selectByPrimaryKey(id);
    }

    public UserTransactionRecord findUserTransactionRecordByTradeNo(String outTradeNo) {
        UserTransactionRecordExample example = new UserTransactionRecordExample();
        example.createCriteria().andTransactionNumberEqualTo(outTradeNo);
        List<UserTransactionRecord> list = userTransactionRecordMapper.selectByExampleWithBLOBs(example);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.iterator().next();
        }
        return null;
    }

    /**
     * 保存用户交易记录，余额发生变化时才保存用户信息，扩展交易记录一般指充值赠送需额外再保存的交易记录
     *
     * @param userTransactionRecord 交易记录
     * @param userInfo              用户(可选)
     * @param extTransactionRecord  额外再保存的交易记录(可选)
     * @return
     */
    public String saveUserTransactionRecord(UserTransactionRecord userTransactionRecord, UserInfo userInfo, UserTransactionRecord extTransactionRecord) {
        userTransactionRecord.setLastUpdateTime(new Date());
        if (StringUtils.isBlank(userTransactionRecord.getId())) {
            userTransactionRecord.setCreateTime(new Date());
            userTransactionRecordMapper.insert(userTransactionRecord);
        } else {
            userTransactionRecordMapper.updateByPrimaryKeySelective(userTransactionRecord);
        }
        if (userInfo != null) {
            JSONObject jsonObject = userInfo.getRecommendJSON();
            if (jsonObject != null && !jsonObject.isNullObject()) {
                String isDiscountStr = jsonObject.getString(UserInfo.RECOMMEND_IS_DISCOUNT);
                if ("0".equals(isDiscountStr)) {
                    String phone = jsonObject.getString(UserInfo.RECOMMEND_PHONE);
                    UserInfo recommend = this.findUserInfoByLogin(phone);
                    recommend.setBalance(recommend.getBalance().add(new BigDecimal(5)));
                    recommend.setFkLevel("1");
                    userInfoMapper.updateByPrimaryKeySelective(recommend);
                    UserTransactionRecord recommendTransactionRecord = new UserTransactionRecord(recommend.getId(), userTransactionRecord.getTransactionNumber(), UserTransactionRecord.Method.余额, UserTransactionRecord.TransactionType.赠送, new BigDecimal(5)).setNote("推荐优惠");
                    recommendTransactionRecord.setDisable(Boolean.FALSE);
                    userTransactionRecordMapper.insert(recommendTransactionRecord);
                    jsonObject.put(UserInfo.RECOMMEND_IS_DISCOUNT, "1");
                    userInfo.setRecommend(jsonObject.toString());
                    userInfoMapper.updateByPrimaryKeySelective(userInfo);
                }
            }
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
        }
        if (extTransactionRecord != null) {
            userTransactionRecordMapper.insert(extTransactionRecord);
        }
        return userTransactionRecord.getId();
    }

    //******************************************** UserDiscount **************************************************************
    public List<UserDisCount> findUserDisCount(String userId, String... userDisCountIds) {
        if (ArrayUtils.isNotEmpty(userDisCountIds)) {
            List<String> ids = Arrays.asList(userDisCountIds);
            UserDisCountExample userDisCountExample = new UserDisCountExample();
            userDisCountExample.or().andFkUserEqualTo(userId).andDisableEqualTo(Boolean.FALSE).andIdIn(ids);
            return userDisCountMapper.selectByExampleWithBLOBs(userDisCountExample);
        }
        return new ArrayList<UserDisCount>();
    }

    public UserDisCount saveUserDisCount(UserDisCount userDisCount) {
        if (StringUtils.isNotBlank(userDisCount.getId())) {
            userDisCountMapper.updateByPrimaryKeySelective(userDisCount);
        } else {
            userDisCount.init();
            userDisCountMapper.insertSelective(userDisCount);
        }
        return userDisCount;
    }
}
